﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MapLibrary.Utility;
using Animation;
using AI;

namespace MapLibrary.Particles
{
    /// <summary>
    /// Pooling for particles.  A Pool is associated with a SpriteType, which is the type
    /// the particles will be created from.  Additionally, the ParticlePool has a reference
    /// to GameWorld so that it may place particles in the current level.
    /// </summary>
    public class ParticlePool<T> : Pool<Particle> where T: Particle, new()
    {
        private GameWorld world;
        private SpriteType type;
        private string particleName;

        public ParticlePool(GameWorld world, SpriteType type, string particleName)
        {
            this.world = world;
            this.type = type;
            this.particleName = particleName;

            Initialize();
        }

        /// <summary>
        /// Construct a Particle.
        /// </summary>
        /// <returns></returns>
        protected override Particle Construct()
        { 
            Particle toEdit = new T(); 
            toEdit.Scale = new Microsoft.Xna.Framework.Vector2(1.0f, 1.0f);
            toEdit.Type = type.Clone();
            toEdit.Type.CurrentState = type.StateList.ElementAt(0).StateName;

            Bot b = BotFactory.CreateBot(type.BotName);
            if (b != null)
            {
                b.Owner = toEdit;
                toEdit.Bot = b;
            }

            toEdit.Update();

            toEdit.ParticleType = particleName;

            return toEdit;
        }

        /// <summary>
        /// Register the particle to the world.  This involves creating a body for the
        /// particle, etc.  This is the same PostNew as SpritePool.
        /// </summary>
        /// <param name="toEdit"></param>
        protected override void PostNew(Particle toEdit)
        {
            toEdit.RegisterToWorld(world);
            toEdit.Rotation = 0.0f;
        }

        /// <summary>
        /// This method simply removes the particle from the current level after
        /// reclaiming it.
        /// </summary>
        /// <param name="toEdit"></param>
        protected override void PostReclaim(Particle toEdit)
        {
            world.CurrentLevel.AddBodyToRemove(toEdit);
        }
    }
}
